<?php

	require_once CORMO_DIR_CORE.'Object.class.php';
	
	/**
	 * Generador de las Class Use<Object> que agregan funcionalidades a las Class Base<Object> para pod�r 
	 * asi generar toda la funcionalidad en la Class Model.
	 *
     * @category cormo
     * @package Generator
     * @author Germán Dario Peraferrer <gperaferrer@gmail.com>
     * @copyright Copyright (c) 2007 Germán Dario Peraferrer - Beetec
     * @version 1.0 Beta
     * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
     * @link http://code.google.com/p/cormoframework/
     * @link http://www.beetec.com.ar
	 */
	
	class UseObject	extends Object {
		
		function __construct($NameObjectORM) {
			return parent::__construct($NameObjectORM);
		}
		
		function __toString() {
			$retun = "";
            $require = "";
			
			/**
			 * Definimos lo Require de la Class
			 */
			
      $require .=	'  require_once CORMO_DIR_BASE."Base'.$this->getConfigObjectName().'.class.php";'."\n";

      // Definimos los Require de las Class / Tabla Asociadas
			foreach($this->getConfigTableAssociate() as $class => $field)	{
	  		$require .=	'  require_once CORMO_DIR_MODEL."'.$class.'.class.php";'."\n";
			}
			
			$retun .= "\n";
						
			/**
			 * Definimos la Class
			 */
			$retun .= '  /**'."\n";
			$retun .= '   * Class generada autom�ticamente cormo.'."\n";
			$retun .= '   * '."\n";
			$retun .= '   * @category cormo'."\n";
			$retun .= '   * @package Use'."\n";
			$retun .= '   * @author Germán Dario Peraferrer <gperaferrer@gmail.com>'."\n";
			$retun .= '   * @copyright Copyright (c) 2007 Germán Dario Peraferrer - Beetec'."\n";
			$retun .= '   * @version 1.0 Beta'."\n";
			$retun .= '   * @license http://www.opensource.org/licenses/bsd-license.php New BSD License'."\n";
			$retun .= '   * @link http://code.google.com/p/cormoframework/'."\n";
			$retun .= '   * @link http://www.beetec.com.ar'."\n";
			$retun .= '   */'."\n";
			$retun .= "\n";
			$retun .= "  class Use".$this->getConfigObjectName()." extends Base".$this->getConfigObjectName()." {\n\n";
			
			/**
			 * Definimos los Atributos
			 */
			foreach($this->getConfigTableAssociate() as $class => $field)	{
				$retun .= "    "."private $".'_'.ucwords($class).";\n";
			}
			
			$retun .= "\n\n";
			
			/**
			 * Definimos el Costructor de la Class
			 */
			
			$retun .= '    function __construct($id = null)  {'."\n";
      $retun .= '      parent::__construct($id);'."\n";
      $retun .=	"    }\n\n";

      /**
       * Definimos los metodos que estan expresados por TbaleAssociate
       */
			foreach($this->getConfigTableAssociate() as $table => $field)	{
				
				switch ($field)	{
					
					case '1:n':
						// Agregamos al require
						$require .= '  require_once CORMO_DIR_BASE_PEER."Peer'.$this->getConfigObjectName().$table.'.class.php";'."\n";
						$require .= '  require_once CORMO_DIR_MODEL."'.$this->getConfigObjectName().ucwords($table).'.class.php";'."\n";

						// Creamos LIST para poder mostrar todos los objetos relacionados en 1:n
						$retun .= '    /**'."\n";
						$retun .= '     * Devuelve todos los objetos de '.ucwords($table).' que han sido relacionados.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @return ArrayObject '.ucwords($table)."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function list'.ucwords($table).'() {'."\n";
						$retun .= '      $pivot = new '.$this->getConfigObjectName().ucwords($table).'();'."\n";
						$retun .= '      $arrObj = new ArrayObject();'."\n";
						$retun .= ''."\n";
						$retun .= '      $arrProperties = array(\'ID'.$this->getConfigObjectName().'\' => array($this->getID(), \'=\', \'\') );'."\n";
						$retun .= ''."\n";
						$retun .= '      foreach(Peer'.$this->getConfigObjectName().ucwords($table).'::getObjectsByProperty($arrProperties) as $pivot)  {'."\n";
						$retun .= '        $arrObj->append($pivot->get'.ucwords($table).'());'."\n";
						$retun .= '      }'."\n";
						$retun .= ''."\n";
						$retun .= '      return $arrObj;'."\n";
						$retun .= '    }'."\n\n";
						
						// Cuenta la cantidad de Registros que han sido ralacionados
						$retun .= '    /**'."\n";
						$retun .= '     * Devuelve la cantidad de objetos '.ucwords($table).' que han sido relacionados.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @return number'."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function count'.ucwords($table).'() {'."\n";
						$retun .= '      $pivot = new '.$this->getConfigObjectName().ucwords($table).'();'."\n";
						$retun .= '      $arrObj = new ArrayObject();'."\n";
						$retun .= ''."\n";
						$retun .= '      $arrProperties = array(\'ID'.$this->getConfigObjectName().'\' => array($this->getID(), \'=\', \'\') );'."\n";
						$retun .= ''."\n";
						$retun .= '      return Peer'.$this->getConfigObjectName().ucwords($table).'::getObjectsByProperty($arrProperties)->count();'."\n";
						$retun .= '    }'."\n\n";
						
						// Creamos ADD para poder agregar relaciones 1:n
						$retun .= '    /**'."\n";
						$retun .= '     * Agrega un '.ucwords($table).' a '.ucwords($this->getConfigObjectName()).'.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @param '.ucwords($table).' $'.strtolower($table)."\n";
						$retun .= '     * @return mixed'."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function add'.$table.'('.ucwords($table).' $'.strtolower($table).') {'."\n";
						$retun .= '      $pivot = new '.$this->getConfigObjectName().ucwords($table).'();'."\n";
						$retun .= '      $pivot->set'.$this->getConfigObjectName().'($this);'."\n";
						$retun .= '      $pivot->set'.ucwords($table).'($'.strtolower($table).');'."\n";
						$retun .= '      return $pivot->save();'."\n";
						$retun .= '    }'."\n\n";

						
						// Creamos DEL para poder eliminar ralaciones 1:n
						$retun .= '    /**'."\n";
						$retun .= '     * Elimina un '.ucwords($table).' de '.ucwords($this->getConfigObjectName()).'.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @param '.ucwords($table).' $'.strtolower($table)."\n";
						$retun .= '     * @return boolean'."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function del'.ucwords($table).'('.ucwords($table).' $'.strtolower($table).') {'."\n";
						$retun .= '      $pivot = new '.$this->getConfigObjectName().ucwords($table).'();'."\n";
						$retun .= ''."\n";
						$retun .= '      $arrProperties = array(\'ID'.$this->getConfigObjectName().'\' => array($this->getID(), \'=\', \'AND\'),'."\n";
						$retun .= '                             \'ID'.ucwords($table).'\' => array($'.strtolower($table).'->getID(), \'=\', \'\') );'."\n";
						$retun .= ''."\n";
						$retun .= '      foreach(Peer'.$this->getConfigObjectName().ucwords($table).'::getObjectsByProperty($arrProperties) as $pivot)  {'."\n";
						$retun .= '      }'."\n";
						$retun .= ''."\n";
						$retun .= '      return $pivot->delete();'."\n";
						$retun .= '    }'."\n\n";
												
    				// Creamos EXISTS para verificar la existencia de una tupla en la relacion 1:n
						$retun .= '    /**'."\n";
						$retun .= '     * Verifica si '.ucwords($table).' esta relacionado con '.ucwords($this->getConfigObjectName()).'.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @param '.ucwords($table).' $'.strtolower($table)."\n";
						$retun .= '     * @return boolean'."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function exists'.ucwords($table).'('.ucwords($table).' $'.strtolower($table).') {'."\n";
						$retun .= '      $pivot = new '.$this->getConfigObjectName().ucwords($table).'();'."\n";
						$retun .= ''."\n";
						$retun .= '      $arrProperties = array(\'ID'.$this->getConfigObjectName().'\' => array($this->getID(), \'=\', \'AND\'),'."\n";
						$retun .= '                             \'ID'.ucwords($table).'\' => array($'.strtolower($table).'->getID(), \'=\', \'\') );'."\n";
						$retun .= ''."\n";
						$retun .= '      foreach(Peer'.$this->getConfigObjectName().ucwords($table).'::getObjectsByProperty($arrProperties) as $pivot)  {'."\n";
						$retun .= '      }'."\n";
						$retun .= ''."\n";
						$retun .= '      if ($pivot->getID() == \'\')'."\n";
						$retun .= '        return false;'."\n";
						$retun .= '      else'."\n";
						$retun .= '        return true;'."\n";
						$retun .= '    }'."\n\n";
						
						break;
						
					default: // Relacion 1:1 especificada por el Campo en schema.php
						// Agregamos al require
						$require .= '  require_once CORMO_DIR_MODEL_QRY."Qry'.ucwords($table).'.class.php";'."\n";

						// Creamos LIST para poder mostrar todos los objetos relacionados en 1:1 mostraria todos los objetos que puedo utilizar para la relacion
						$retun .= '    /**'."\n";
						$retun .= '     * Devuelve todos los objetos de '.ucwords($table)."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @return ArrayObject '.ucwords($table)."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function list'.ucwords($table).'() {'."\n";
						$retun .= '      $'.strtolower($table).' = new '.ucwords($table).'();'."\n";
						$retun .= '      return Qry'.ucwords($table).'::getObjectsAll();'."\n";
						$retun .= '    }'."\n\n";
						
						// Creamos el Setter que sobreescribe el metodo del Atributo mardao como relacionde la Asociacion
						$retun .= '    /**'."\n";
						$retun .= '     * Asocia el objeto '.ucwords($table).' a '.ucwords($this->getConfigObjectName()).'.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @param '.ucwords($table).' $'.strtolower($table)."\n";
						$retun .= '     * @return void'."\n";
						$retun .= '     */'."\n";
						$retun .= "    public function set".ucwords($table).'('.ucwords($table).' $'.strtolower($table).")  {\n";
						$retun .= '      parent::set'.ucwords($field).'($'.strtolower($table).'->getID());'."\n";
						$retun .= '      $this->_'.$table.' = new '.$table.'($'.strtolower($table).'->getID());'."\n";
						$retun .= "    }\n\n";
						
						// Creamos el Getter del Objeto de Composicion
						$retun .= '    /**'."\n";
						$retun .= '     * Obtiene el objeto '.ucwords($table).' asociado con '.ucwords($this->getConfigObjectName()).'.'."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @return '.ucwords($table)."\n";
						$retun .= '     */'."\n";
						$retun .= "    public function get".ucwords($table)."()  {\n";
						$retun .= '      if (!$this->_'.ucwords($table).' instanceof '.ucwords($table).')'."\n";
						$retun .= '        $this->_'.ucwords($table).' = new '.ucwords($table).'($this->getID'.ucwords($table).'());'."\n";
						$retun .= '      return $this->_'.ucwords($table).';'."\n";
						$retun .= "    }\n\n";

				}
				
			}

			/**
			 * Creacion de los metodos listAssociate para poder obtener quienes nos has relacioando
			 */
			
			// Buscamos si el objeto es parte de una relacion en otro objeto, de esta manera creamos un metodo para obtener sus padres
			// Obtnemos todas las Aosciaciones del ORM
			foreach($this->getORMTableAssociate() as $ormTable => $ormObjets) {
				// Buscamos si este Objeto posee relaciones
				foreach($ormObjets as $ormObjet => $ormAssociate) {
					// Identificamos si este posee asosiaciones 1:1
					if (($this->getConfigObjectName() == $ormObjet) && ($ormAssociate != '1:n')) {
						// Agregamos el requiere para poder hacer las consultas
						$require .=	'  require_once CORMO_DIR_MODEL."'.ucwords($ormTable).'.class.php";'."\n";
			  		$require .=	'  require_once CORMO_DIR_BASE_PEER."Peer'.ucwords($ormTable).'.class.php";'."\n";
						  		
						$retun .= '    /**'."\n";
						$retun .= '     * Devuelve todos los objetos de '.ucwords($ormTable).' que se han relacionado con '.$this->getConfigObjectName()."\n";
						$retun .= '     *'."\n";
						$retun .= '     * @return ArrayObject '.ucwords($ormTable)."\n";
						$retun .= '     */'."\n";
						$retun .= '    public function listAssociate'.ucwords($ormTable).'() {'."\n";
						$retun .= '      $properties = array("'.$ormAssociate.'" => array($this->getID(), "=", ""));'."\n";
						$retun .= '      return Peer'.ucwords($ormTable).'::getObjectsByProperty($properties);'."\n";
						$retun .= '    }'."\n\n";
					}
				}
			}
			
            /**
             * Creacion del Metodo ADD
             */
    	
            $arrSetObjects = array();
            $arrTable = array();
            $arrField = array();
            // Buscamos los objetos que estan relacionados 1:1 para poder definir el metodo ADD
            foreach($this->getConfigTableAssociate() as $table => $field)	{
                if (($field != '1:n') && ($field != 'n:n'))	{
    				array_push($arrTable, $table);
        			array_push($arrField, $field);
            	}
            }

            // Array con los Objetos que poseen Relacion 1:1
            $arrSetObjects = @array_combine($arrTable, $arrField);
			
            // Creamos una cadena con los Atributos que se deberan pasar como parametro al metodo ADD
            $cadParametros = '';
            foreach($this->getConfigFieldsNotKey() as $atributo) {
    			// Verificamos si el atributo se trata de una relacion 1:1
        		if (@in_array($atributo, $arrSetObjects)) {
            		$cadParametros .= array_search($atributo, $arrSetObjects).' $'.array_search($atributo, $arrSetObjects).', ';
                } else {
    				$cadParametros .= '$'.$atributo.', ';
                }
    		}

        	// Eliminamos la Ultima Coma de los Atributos para el Metodo ADD
            $cadParametros = substr($cadParametros, 0, strlen($cadParametros)-2);
			
    		$retun .= '    /**'."\n";
        	$retun .= '     * Crea un nuevo objeto '.ucwords($this->getConfigObjectName())."\n";
            $retun .= '     *'."\n";
    		// Buscamos todos los parametros del metodo
        	foreach($this->getConfigFieldsNotKey() as $atributo)	{
            	// Verificamos si el atributo se trata de una relacion 1:1
                if (@in_array($atributo, $arrSetObjects))
                    $retun .= '     * @param '.array_search($atributo, $arrSetObjects).' $'.array_search($atributo, $arrSetObjects)."\n";
    			else
        			$retun .= '     * @param mixed '.'$'.$atributo."\n";
            	}
    		$retun .= '     * @return boolean'."\n";
        	$retun .= '     */'."\n";
            $retun .= '    function add('.$cadParametros.')'." {\n";
        	// Creamos todas las llamadas a los metodos SET para la CLASS actual
        	foreach($this->getConfigFieldsNotKey() as $atributo)	{
            	// Verificamos si el atributo se trata de una relacion 1:1
                if (@in_array($atributo, $arrSetObjects))
                    $retun .= '      $this->set'.array_search($atributo, $arrSetObjects).'($'.array_search($atributo, $arrSetObjects).');'."\n";
    			else
        			$retun .= '      $this->set'.$atributo.'($'.$atributo.');'."\n";
            }
        	$retun .= '      return $this->save();'."\n";
        	$retun .= "    }\n\n";
			
    		/**
         	 * Cerramos la Class
    		 */
			
        	$retun .= "  }\n";
		
            return $require.$retun;
		}

	}
	
?>